package com.hydl.power.aop;

import com.hydl.power.aop.annotation.LogAnnotation;
import com.hydl.power.mapper.LogMapper;
import com.hydl.power.pojo.Log;
import com.hydl.power.utils.AddressUtils;
import com.hydl.power.utils.IdUtil;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.UserAgent;
import eu.bitwalker.useragentutils.Version;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.Base64;
import java.util.Date;
import java.util.Map;


@Aspect
@Component
public class LogAop {


    @Autowired
    private LogMapper logMapper;


    @Pointcut("execution(public * com.hydl.power.controller.*.*(..)))")
    public void LogAspect(){

    }


    @Before("LogAspect()")
    public void doBeforeAdvice(JoinPoint joinPoint){
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
        if (logAnnotation != null) {
            Log log=new Log();
            log.setId(IdUtil.getRandomString(8));
            log.setLogname(request.getRemoteHost());
            log.setLoglink(request.getRequestURL().toString());
            Map<String, String[]> params = request.getParameterMap();
            if(params.size()>0){
                StringBuilder stringBuilder = new StringBuilder();
                for (Map.Entry<String, String[]> param : params.entrySet()) {
                    stringBuilder.append(","+param.getKey()+"="+StringUtils.join(param.getValue()));
                }
                if (StringUtils.isNotBlank(stringBuilder)){
                    String param = stringBuilder.substring(1);
                    log.setLogparam(param);
                }
            }
            if(StringUtils.isNotBlank(request.getQueryString())){
                try {
                    String decode = URLDecoder.decode(request.getQueryString(), "utf-8");
                    log.setLogparam(decode);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
            //浏览器
            Browser browser = UserAgent.parseUserAgentString(request.getHeader("User-Agent")).getBrowser();
            Version version = browser.getVersion(request.getHeader("User-Agent"));
            if(version!=null){
                log.setLogbrowser(browser.getName());
            }
            //解析LogAnnotation注解
            /*String methodName = joinPoint.getSignature().getName();
            Method method = currentMethod(joinPoint,methodName);
            LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
            System.out.println(logAnnotation.module()+logAnnotation.description());*/
            String module = logAnnotation.module();
            String description = logAnnotation.description();
            log.setCropname(module+"/"+description);
            //ip地址
            String ip = AddressUtils.getIp(request);
            log.setLogip(ip);
            //ip位置
            String addresses = AddressUtils.getIpAddress(ip);
            log.setLogIpAddress(addresses);
            log.setLogmethod(request.getRequestURI());
            String username="";
            String url=request.getRequestURI();
            if (url.contains("/login/login") || url.contains("/app/login")){
                username = StringUtils.join(params.get("userName"));
            }else {
              if(username != null || !username.equals("")){
                username = request.getHeader("username");
              }
                try {
                    username = new String(Base64.getDecoder().decode(username), "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
            log.setLoguser(username);
            log.setLogdate(new Date());
            logMapper.insert(log);
        }

    }


    @After("LogAspect()")
    public void doAfterAdvice(){

    }


    @AfterReturning("LogAspect()")
    public void doAfterReturningAdvice(){
    }


    @AfterThrowing("LogAspect()")
    public void doAfterThrowingAdvice(){
    }


    /**
     * 获取当前执行的方法
     *
     * @param joinPoint  连接点
     * @param methodName 方法名称
     * @return 方法
     */
    /*private Method currentMethod(JoinPoint joinPoint, String methodName) {
        *//**
         * 获取目标类的所有方法，找到当前要执行的方法
         *//*
        Method[] methods = joinPoint.getTarget().getClass().getMethods();
        Method resultMethod = null;
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                resultMethod = method;
                break;
            }
        }
        return resultMethod;
    }*/

}
